48장. 백엔드 Skill 만들기 — API 구현 · 장애 분석 · Migration Review
47장에서 구조를 봤다.
이 장은 실제로 값어치가 큰 것들이다.
6부에서 다룬 절차들을 Skill로 옮긴다.
어떤 것부터 만드는가
우선순위는 두 축이다.
빈도 × 빠뜨렸을 때의 대가
| Skill | 빈도 | 사고 시 대가 |
|---|---|---|
| 마이그레이션 검토 | 주 1~2회 | 🔥 높음 |
| 장애 분석 | 주 2~3회 | 높음 |
| API 추가 | 주 3~5회 | 중간 |
| 보안 검토 | PR마다 | 높음 |
| 세션 인계 | 매일 | 낮음 |
첫 번째부터 만든다.
47장에서 이미 초안을 봤다.
1️⃣ API 추가
26장의 절차를 그대로 옮긴다.
---
name: add-api
description: 새 REST API 엔드포인트를 추가한다. API 추가·수정,
새 엔드포인트 구현 요청 시 사용한다.
---
# API 추가
## 1. 참고할 API 찾기
가장 최근에 추가된 유사 API를 찾는다.
```bash
git log --diff-filter=A --name-only --since="6 months ago" \
-- '*Controller.kt' | head -20
```
⚠️ 오래된 API를 참고하면 옛 패턴이 복제된다.
## 2. 스펙 먼저 제시
구현 전에 아래를 제시하고 승인을 받는다.
- 경로, 메서드, 요청/응답 JSON
- 실패 케이스별 상태 코드와 에러 코드
- 참고한 API와 다른 점
## 3. 구현
계층 순서: Controller → Facade → Service → Repository
## 4. 체크리스트
- [ ] 응답이 `ApiResponse<T>` 로 감싸져 있는가
- [ ] 엔티티를 직접 반환하지 않는가
- [ ] 기존 예외를 재사용했는가 (새로 만들지 않았는가)
- [ ] 권한 검사가 있는가 — 참고 API와 동일한 정책인가
- [ ] 요청 검증이 DTO 애노테이션으로 되어 있는가
- [ ] 실패 케이스 테스트가 있는가
- [ ] 내부에서 이 Service를 호출하는 다른 모듈이 있는가
## 5. 완료 조건
- 정상/실패 케이스 테스트 통과
- `./gradlew ktlintCheck` 통과
🔥 4번의 네 번째 항목이 32장에서 본 그 사고를 막는다.
권한 애노테이션 누락은 조용히 통과하므로
체크리스트에 없으면 놓친다.
2️⃣ 장애 분석
33장의 순서다.
---
name: incident
description: 운영 장애를 분석한다. 에러 발생, 알람, 이상 동작
신고를 받았을 때 원인을 찾기 위해 사용한다.
---
# 장애 분석
## 원칙
- 결론을 먼저 세우지 않는다. 증상에서 시작한다
- 수정하기 전에 재현 테스트를 만든다
## 1. 증상 정리
아래를 확인한다. 모르면 모른다고 기록한다.
- 언제부터 (정확한 시각 범위)
- 몇 건 / 전체 대비 비율
- 영향받은 대상의 공통점
- 최근 배포·설정 변경 여부
## 2. 로그 수집
⚠️ 전체 로그를 읽지 않는다. 시간 범위나 추적 ID로 먼저 자른다.
좁힐 키워드가 없으면 무엇으로 필터링할지 먼저 제안한다.
## 3. 가설 세우기
가설을 3개 이상, 유력한 순으로. 각각에 대해:
- 근거가 되는 코드 위치 (파일:줄)
- 이 가설이 맞다면 로그·DB에 무엇이 남아 있어야 하는가
- 확인 방법
## 4. 검증
하나씩 확인한다. 틀린 가설도 기록에 남긴다.
## 5. 재현 테스트
원인이 확인되면 재현 테스트를 먼저 만든다. 지금은 실패해야 정상이다.
## 6. 수정과 회귀 확인
## 7. 기록
`tasks/incident-{날짜}.md` 에 증상 / 원인 / 조치 / 재발 방지를 남긴다.
⚠️ 7번을 빠뜨리면 같은 장애를 두 번 분석한다.
3️⃣ 마이그레이션 검토
47장의 예시를 확장한다.
---
name: migration-review
description: DB 마이그레이션을 검토한다. 마이그레이션 작성 후,
스키마 변경 PR 리뷰 시 사용한다.
---
# 마이그레이션 검토
## 확인 방식
각 항목에 대해 "확인함 / 문제있음 / 해당없음" 을 명시한다.
"특별한 문제 없음" 같은 뭉뚱그린 답을 하지 않는다.
## 스키마 변경
- [ ] NOT NULL 을 백필 전에 걸지 않았는가
- [ ] 컬럼 rename 대신 추가-이행-제거를 따랐는가
- [ ] 타입 변경·기본값 추가가 테이블 rewrite 를 유발하지 않는가
## 잠금과 규모
- [ ] 대상 테이블의 예상 행 수를 확인했는가
- [ ] 100만 건 이상이면 온라인 인덱스 생성을 썼는가
## 배포 안전성
- [ ] 구버전 앱 + 신버전 스키마 조합에서 동작하는가
- [ ] 신버전 앱 + 구버전 스키마 조합에서 동작하는가
- [ ] 롤백 방법이 있는가. 없으면 그 사실이 명시되어 있는가
## 금지
- 마이그레이션을 실행하지 않는다
- 파일을 수정하지 않는다. 문제만 보고한다
🔥 배포 안전성의 두 항목이 27장에서 본 사고를 막는다.
Agent는 최종 상태만 보고 배포 중간 상태를 고려하지 않는다.
체크리스트가 그것을 강제한다.
4️⃣ 보안 검토
32장의 항목별 답변을 Skill로 만든다.
---
name: security-review
description: 변경사항을 보안 관점에서 검토한다. PR 전, 인증·권한·
외부 입력을 다루는 코드를 수정했을 때 사용한다.
---
# 보안 검토
## 대상
`git diff` 로 이번 변경만 본다. 전체 코드베이스를 훑지 않는다.
## 항목
각 항목에 "확인함 / 문제있음 / 해당없음" 을 명시한다.
문제는 파일:줄과 함께 보고한다.
- [ ] 신규·수정 엔드포인트에 인증이 필요한가. 적용되어 있는가
- [ ] 리소스 소유자 검증이 있는가 (남의 데이터 조회 가능성)
- [ ] 외부 입력이 검증되는가
- [ ] 문자열 연결로 만든 쿼리가 있는가
- [ ] 정렬·필터 파라미터가 화이트리스트로 검증되는가
- [ ] 하드코딩된 키·토큰·비밀번호가 있는가
- [ ] 테스트 코드에 실제 자격증명이 들어갔는가
- [ ] 로그에 개인정보가 찍히는가
- [ ] 응답에 불필요한 필드가 노출되는가
## 금지
- 코드를 수정하지 않는다
- 취약점을 시연하는 코드를 작성하지 않는다
⚠️ “각 항목에 명시” 가 이 Skill의 핵심이다.
없으면 “특별한 문제가 없습니다” 한 줄이 돌아온다.
Skill 안에 명령을 넣는다
체크리스트만이 아니라 실행할 명령도 넣는다.
영향 범위 확인 절에 이런 것을 적어둔다.
# 이 Service 를 호출하는 곳
grep -rn "OrderCancelService" --include=*.kt src/main
# 최근 이 파일과 함께 바뀐 파일 (34장)
git log --format="%H" -20 -- <파일> | \
xargs -I{} git show --name-only --format="" {} | sort | uniq -c | sort -rn
두 번째 명령은 매번 기억해내기 어렵다.
한 번 적어두면 그 뒤로는 Skill이 기억한다.
팀의 Skill 목록
여섯 개쯤 쌓이면 목록 자체가 팀 자산이 된다.
.claude/skills/
add-api/ incident/ migration-review/
security-review/ handoff/ boundary-check/
마지막 것은 8부의 조사 절차 중
반복되는 것을 Skill로 만든 것이다.
이 장의 핵심
- 빈도와 사고 시 대가를 곱해 만들 순서를 정한다
- API 추가 체크리스트의 권한 검사 항목이 조용한 사고를 막는다
- 장애 분석 Skill은 “결론을 먼저 세우지 않는다” 로 시작한다
- 가설을 반증 가능한 형태로 요구하는 것을 절차에 넣는다
- 장애 기록을 빠뜨리면 같은 장애를 두 번 분석한다
- 마이그레이션 체크리스트의 배포 중간 상태 항목이 핵심이다
- 검토형 Skill은 항목별로 “확인함/문제있음/해당없음” 을 강제한다
- 그것이 없으면 “특별한 문제 없음” 한 줄이 돌아온다
- 자주 쓰는 조사 명령도 Skill에 넣어두면 기억해낼 필요가 없다